import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:jd_flutter/base/foundation/flutter_extension.dart';
import 'package:jd_flutter/base/foundation/jd_convert.dart';
import 'package:jd_flutter/base/utils/db/db_storage.dart';
import 'package:jd_flutter/base/utils/db/storage_model.dart';
import 'package:jd_flutter/base/utils/jd_log.dart';
import 'package:jd_flutter/base/widget/basic/jd_app_bar.dart';
import 'package:jd_flutter/base/widget/ui/jd_text_field.dart';
import 'package:sqflite/sqflite.dart';

class DBDemoPage extends StatefulWidget {
  const DBDemoPage({Key? key}) : super(key: key);

  @override
  State<DBDemoPage> createState() => _DBDemoPageState();
}

class _DBDemoPageState extends State<DBDemoPage> {
  List<StorageModel> noteList = [];
  int? id;
  int count = 0;
  String? name;
  int? age;

  DbStorage storage = DbStorage.instance;
  @override
  void initState() {
    super.initState();

    _doInit();
  }

  TextEditingController textEditingController = TextEditingController();
  TextEditingController ageEditingController = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: JDAppBar(
        title: '数据库demo',
      ),
      body: Column(
        children: [
          Text('count:$count'),
          Row(
            children: [
              SizedBox(
                width: 120,
                height: 50,
                child: JDTextField(
                  'name String',
                  textEditController: textEditingController,
                ),
              ),
              20.hGap,
              SizedBox(
                width: 80,
                height: 50,
                child: JDTextField(
                  'age int',
                  textEditController: ageEditingController,
                ),
              ),
              TextButton(
                  onPressed: () {
                    if (textEditingController.text.isNotEmpty) {
                      _doSave(textEditingController.text,
                          JDConvert.asIntNotNull(ageEditingController.text));
                    }
                  },
                  child: const Text('数据库增加一条'))
            ],
          ),
          TextButton(onPressed: _loadAll, child: const Text('刷新')),
          Row(
            children: [
              Expanded(
                child: TextField(
                  decoration: const InputDecoration(hintText: 'input id'),
                  onChanged: (value) {
                    if (value.isNotEmpty) {
                      id = int.parse(value);
                    }
                  },
                ),
              ),
              Expanded(
                  child: Column(
                children: [
                  TextField(
                    decoration: const InputDecoration(hintText: 'name'),
                    onChanged: (value) => name = value,
                  ),
                  TextField(
                    decoration: const InputDecoration(hintText: 'age int'),
                    onChanged: (value) {
                      if (value.isNotEmpty) {
                        age = JDConvert.asIntNotNull(value);
                      }
                    },
                  ),
                ],
              )),
              TextButton(onPressed: _updateContent, child: const Text('Update'))
            ],
          ),
          20.vGap,
          Expanded(
              child: ListView.builder(
                  itemCount: noteList.length,
                  itemBuilder: (BuildContext _, int inx) => _itemWidget(inx)))
        ],
      ),
    );
  }

  _itemWidget(int inx) {
    StorageModel model = noteList[inx];
    return Column(
      children: [
        Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: [
            Text('id:${model.id},content:${model.content}'),
          ],
        ),
        ElevatedButton(
            onPressed: () => _doDelete(model), child: const Text('Delete'))
      ],
    );
  }

  String dbName = 'test';
  String tableName = 'tableName1';

  Database? database;
  JDStorageTool? storageTool;
  void _doInit() async {
    // 每次TestDbContentModel结构变化 version +1
    Database? db = storage.dateBaseMap[dbName];
    if (db != null) {
      database = db!;
    } else {
      // 每次更改表结构 version + 1
      database =
          await openDatabase(dbName, version: 1, onCreate: (db, version) {
        // 在数据库首次创建时执行的操作
      }, onUpgrade: (db, oldVersion, newVersion) async {
        // 在数据库升级时执行的操作
        if (oldVersion == 1 && newVersion == 2) {
          // version增加升级数据库,要进行旧版本到新版本数据迁移
          // 如果当前数据库版本为1，目标版本为2，执行数据迁移操作
        }
      });
    }
    if (database != null) {
      // name TEXT, value INTEGER, num REAL; 需要查询的属性 必须单独写成属性
      storageTool = JDStorageTool(database!, tableName,
          'create table if not exists $tableName (id integer primary key autoincrement, content text)');
      _loadAll();
    }
  }

  @override
  void dispose() {
    jdLog('db dispose');
    textEditingController.dispose();
    ageEditingController.dispose();
    storageTool?.destroy();

    super.dispose();
  }

  ///保存数据
  void _doSave(String nameValue, int age) {
    TestDbContentModel contentModel =
        TestDbContentModel.fromJson({'name': nameValue, 'age': age});
    storageTool
        ?.saveData(StorageModel(content: jsonEncode(contentModel.toJson())));
    _loadAll();
  }

  ///查询数据
  void _loadAll() async {
    var list = await storageTool?.getAllData() ?? [];
    jdLog('list.length--  ${list.length}');
    setState(() {
      noteList = list;
    });
    _getCount();
  }

  ///更新数据
  void _updateContent() {
    if (id == null || name == null) return;
    TestDbContentModel contentModel =
        TestDbContentModel.fromJson({'name': name, 'age': age});
    var model =
        StorageModel(id: id, content: jsonEncode(contentModel.toJson()));
    storageTool?.update(model);
    _loadAll();
  }

  ///删除数据
  void _doDelete(StorageModel model) {
    storageTool?.deleteData(model.id!);
    _loadAll();
  }

  ///汇总计数
  void _getCount() async {
    var count = await storageTool?.getDataCount() ?? 0;
    setState(() {
      this.count = count;
    });
  }
}

class TestDbContentModel {
  String name = '';
  int age = 0;

  TestDbContentModel.fromJson(Map<String, dynamic> json) {
    name = json['name'];
    age = json['age'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = <String, dynamic>{};
    data['name'] = name;
    data['age'] = age;
    return data;
  }
}
